﻿using System;
using System.Drawing;
using System.IO;
using System.Windows.Forms;
using Emgu.CV;
using Emgu.CV.Structure;
using Emgu.CV.UI;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Sebarf.Diagnostics.Interfaces;

namespace Tests.Basics.UI {
	public partial class PersonCountingByColour : Form {
		private readonly ImageBox m_capturedImageBox;

		private readonly ImageBox m_motionImageBox;
		private string m_imageName;

		public PersonCountingByColour() {
			InitializeComponent();

			try {
				m_capturedImageBox = new ImageBox(); //create an image viewer
				m_motionImageBox = new ImageBox(); //create an image viewer
				panel2.Controls.Add(m_capturedImageBox);
				panel1.Controls.Add(m_motionImageBox);
				m_capturedImageBox.Height = panel2.Height;
				m_capturedImageBox.Width = panel2.Width;
				m_motionImageBox.Dock = DockStyle.Fill;

				DoWork();
			}
			catch (Exception ex) {
				Logger.WriteError(ex.Message);
				Assert.Fail(ex.Message);
			}
		}

		private void LoadImage() {
		}

		private void cmdRun_Click(object sender, EventArgs e) {
			DoWork();
		}

		private void DoWork() {
			if (String.IsNullOrEmpty(m_imageName)) {
				m_imageName = "Sample_02242.jpg";
			}
			string outFileName = "c:\\Output.data";
			if (File.Exists(outFileName)) {
				File.Delete(outFileName);
			}

			var image = new Image<Bgr, Byte>(m_imageName);
			Image<Bgr, byte> toDisplay = image.Clone();

			GeneratePixelValuesBlob(image.PyrDown().PyrDown(), outFileName);

			// search quadrate for line one
			int height = image.Height - 1;
			int width = image.Width;
			int size = 60;
			int offset = 1;
			try {
				double largeValue = Math.Max(searchSizeFactor.Value, searchFactorMax.Value);
				double minValue = Math.Min(searchSizeFactor.Value, searchFactorMax.Value);
				if (largeValue == minValue) {
					largeValue++;
				}
				size = (int)((minValue + Math.Abs(largeValue - minValue) * ((height - offset) / (double)height)));
				//size =  (int)((double)(height - offset) * (searchSizeFactor.Value / 100.0));
				while (size > 2 && (height - size - offset) > 0) {
					size = (int)((minValue + Math.Abs(largeValue - minValue) * ((height - offset) / (double)height)));
					for (int i = size / 2; i < (width - size / 2) - 1; i += rasterSize.Value) {
						double middleValue = image[height - size / 2 - offset, i].Green;
						double topLeftValue = image[height - offset, i - size / 2].Green;
						double topRightValue = image[height - offset, i + size / 2].Green;
						double bottomLeftValue = image[height - size - offset, i - size / 2].Green;
						double bottomRightValue = image[height - size - offset, i + size / 2].Green;

						double middleValueRed = image[height - size / 2 - offset, i].Red;
						double topLeftValueRed = image[height - offset, i - size / 2].Red;
						double topRightValueRed = image[height - offset, i + size / 2].Red;
						double bottomLeftValueRed = image[height - size - offset, i - size / 2].Red;
						double bottomRightValueRed = image[height - size - offset, i + size / 2].Red;

						double middleValueBlue = image[height - size / 2 - offset, i].Blue;
						double topLeftValueBlue = image[height - offset, i - size / 2].Blue;
						double topRightValueBlue = image[height - offset, i + size / 2].Blue;
						double bottomLeftValueBlue = image[height - size - offset, i - size / 2].Blue;
						double bottomRightValueBlue = image[height - size - offset, i + size / 2].Blue;

						//image.Draw(new CircleF(new PointF(i, height - size / 2), 1), new Bgr(0, 0, 255), 2);
						//image.Draw(new CircleF(new PointF(i - size / 2, height), 1), new Bgr(0, 255, 0), 2);
						//image.Draw(new CircleF(new PointF(i + size / 2, height), 1), new Bgr(255, 0, 0), 2);
						//image.Draw(new CircleF(new PointF(i - size / 2, height - size), 1), new Bgr(0, 255, 0), 2);
						//image.Draw(new CircleF(new PointF(i + size / 2, height - size), 1), new Bgr(255, 0, 0), 2);
						//Abstand

						int minDiff = minDifference.Value;
						int middleValueMin = minIntensity.Value;

						topRightValue += minDiff;
						bottomRightValue += minDiff;
						topLeftValue += minDiff;
						bottomLeftValue += minDiff;

						topRightValueRed += minDiff;
						bottomRightValueRed += minDiff;
						topLeftValueRed += minDiff;
						bottomLeftValueRed += minDiff;

						topRightValueBlue += minDiff;
						bottomRightValueBlue += minDiff;
						topLeftValueBlue += minDiff;
						bottomLeftValueBlue += minDiff;

						//middleValueBlue -= 20;
						if (middleValue > topLeftValue && middleValue > topRightValue && middleValue > bottomLeftValue &&
							middleValue > bottomRightValue && middleValue > middleValueMin && middleValueRed > topLeftValueRed &&
							middleValueRed > topRightValueRed && middleValueRed > bottomLeftValueRed &&
							middleValueRed > bottomRightValueRed && middleValueBlue > middleValueMin && middleValueBlue > topLeftValueBlue &&
							middleValueBlue > topRightValueBlue && middleValueBlue > bottomLeftValueBlue &&
							middleValueBlue > bottomRightValueBlue && middleValueRed > middleValueMin) {
							//var subImage = image.GetSubRect(new Rectangle(i - size / 2, height - offset-size, size/2, size/2));

							//    Bgr d;
							//MCvScalar s;
							//subImage.AvgSdv(out d, out s);
							//double sTotal = s.v0 + s.v1 + s.v2 + s.v3;
							//Logger.WriteDebug(sTotal.ToString());
							//if (sTotal > 100) {

							//image.Draw(new Rectangle(width - size, height - size, size, size), new Bgr(0, 0, 255), 2);
							toDisplay.Draw(new CircleF(new PointF(i, height - size / 2 - offset), size / 2), new Bgr(0, middleValue, 0),
											2);
							//}
						}

						//var topLeftValue== image [size / 2].Green;
					}

					offset += rasterSize.Value;
				}
				m_capturedImageBox.Image = image;
				m_motionImageBox.Image = toDisplay;
			}
			catch (Exception ex) {
				Logger.WriteDebug(ex.Message);
			}
		}

		private void GeneratePixelValuesBlob(Image<Bgr, byte> image, string outFileName) {
			StreamWriter outPutFile = File.AppendText(outFileName);
			string tmp = string.Empty;
			for (int i = 0; i < image.Height; i++) {
				for (int y = 0; y < image.Width; y++) {
					outPutFile.WriteLine(i + " " + y + " " + (255.0 - (image[i, y].Green)) + " ");
				}
			}
			outPutFile.Close();
		}

		private void vScrollBarIntensitity_Scroll(object sender, ScrollEventArgs e) {
		}

		private void minIntensity_Scroll(object sender, ScrollEventArgs e) {
			DoWork();
		}

		private void minDifference_Scroll(object sender, ScrollEventArgs e) {
			DoWork();
		}

		private void searchSizeFactor_Scroll(object sender, ScrollEventArgs e) {
			DoWork();
		}

		private void button1_Click(object sender, EventArgs e) {
			var dialog = new OpenFileDialog();
			dialog.Filter = "Bildier |*.jpg";
			DialogResult res = dialog.ShowDialog();
			m_imageName = dialog.SafeFileName;
			DoWork();
		}

		private void label3_Click(object sender, EventArgs e) {
		}

		private void searchFactorMax_Scroll(object sender, ScrollEventArgs e) {
			DoWork();
		}

		private void rasterSize_Scroll(object sender, ScrollEventArgs e) {
			DoWork();
		}
	}
}